
#include <stdint.h>
#include <stdlib.h>
#include <Utility.h>
#include "tag_type.h"
#include "HIDProx.h"
#include "id_card.h"
#include "bsp.h"
#include "simple_protocol.h"
#include "Log.h"

#include <Reader/Reader.h>
#include <Reader/ReaderLF.h>
#include <Reader/ReaderBLE.h>
#include <Reader/ReaderHidBLE.h>

void fun_id_read_start(void);

void fun_id_stop(void);

int fun_id_get_id(uint8_t* uid);

int fun_id_get_hid(HidProxTag_T* info);

int BLE_RequestEndpointClose(void);
int BLE_FindGattServerAttribute(uint16_t * attrhandle);
int BLE_GetGattServerAttributeValue(uint16_t AttrHandle, uint8_t* data, uint8_t* len);
int close_BLE_Init(void);
int open_BLE_Init(void);

static void RfTag_Set(SimpleTag_T* rfTag, uint8_t type, uint8_t uid_bit, uint8_t uid_len, const void* uid){
	memcpy(rfTag->uid, uid, uid_len);
	rfTag->ulen = uid_len;
	rfTag->ubit = uid_bit;
	rfTag->type = type;
}

static int RfTag_Compare(const SimpleTag_T* tag1, const SimpleTag_T* tag2){
	if(tag1->type != tag2->type){
		return 1;
	}

	if(tag1->ulen != tag2->ulen){
		return 2;
	}

	if(memcmp(tag1->uid, tag2->uid, tag1->ulen)){
		return 3;
	}
	
	return 0;
}

static void RfTag_Clear(SimpleTag_T* rfTag){
	rfTag->ulen = 0;
}

typedef struct {
	SimpleTag_T hf;		//高频卡
	SimpleTag_T lf;		//低频卡
}Tag_T;


static void rf_response_tag(buffer_t* response, const SimpleTag_T *tag){
	if(tag){
		uint8_t result = 1; 		//Result
		net_buf_simple_add_u8(response, result);
		net_buf_simple_add_u8(response, tag->type); //type
		net_buf_simple_add_u8(response, tag->ubit); //bit count
		net_buf_simple_add_u8(response, tag->ulen); //id length
		net_buf_simple_add_mem(response, tag->uid, tag->ulen); //id
	}
	else{
		net_buf_simple_add_u8(response, 0);
	}
}


static int rf_check_lf_type(uint32_t flags, const SimpleTag_T* tag){
	switch(tag->type){
	case LFTAG_EM4102: {
		if(TAG_FLAG_CHECK( flags, TAG_MASK_EM4102))//EM4x02/CASI-RUSCO (ID Card)
		{
			return 1;
		}
	}
	break;
	case LFTAG_HIDPROX: {
		if(TAG_FLAG_CHECK( flags, TAG_MASK_HIDPROX))//EM4x02/CASI-RUSCO (ID Card)
		{
			return 1;
		}
	}
	break;
	default:
		break;
	}
	return 0;
}

static int rf_verify_tag(SimpleTag_T* tag){
	if(tag->type != LFTAG_EM4102){
		return 1;
	}
	
	for (int i = 0; i < tag->ulen; ++i){
		if(tag->uid[i] != 0){
			return 1;
		}
	}
	
	return 0;
}


static int rf_search_lf(uint32_t flags, SimpleTag_T* tag){
	int ret = -1;
	uint32_t type = 0;
	
	if(TAG_FLAG_CHECK( flags, TAG_MASK_EM4102))//EM4x02/CASI-RUSCO (ID Card)
	{
		type |= RFID_ITF_TAG_ID;
	}
	
	if(TAG_FLAG_CHECK( flags, TAG_MASK_HIDPROX))//HID Prox
	{
		type |= RFID_ITF_TAG_HID;
	}
	
	ret = Reader_LF_Read(type, tag);
	if(!ret){
		if(!rf_check_lf_type(flags, tag)){
			ret = -1;
		}
	}
	
	if(!ret){
		LOG_SBUF("lf", tag->uid, tag->ulen);
		if(!rf_verify_tag(tag)){
			ret = -1;
		}
	}

	return ret;
}

static int rf_search_ble(SimpleTag_T* tag){
	int ret = rhb_poll(tag->uid, &tag->ulen);
	if(ret){
		return ret;
	}
	tag->ubit = tag->ulen * 8;
	tag->type = HFTAG_HIDICLASS;
	//HID BLE连接标志
	reader.bleFlags = 0x01;
	return 0;
}


static uint16_t hftype2mask(uint16_t type){
	switch(type){
	case HFTAG_MIFARE: return PHAC_DISCLOOP_POS_BIT_MASK_A;
	case HFTAG_ISO14443B: return PHAC_DISCLOOP_POS_BIT_MASK_B;
	case HFTAG_HIDICLASS: return PHAC_DISCLOOP_POS_BIT_MASK_A | PHAC_DISCLOOP_POS_BIT_MASK_B;
	case HFTAG_ISO15693: return PHAC_DISCLOOP_POS_BIT_MASK_V;
	case HFTAG_FELICA: return (PHAC_DISCLOOP_POS_BIT_MASK_F212 | PHAC_DISCLOOP_POS_BIT_MASK_F424);
	}
	return 0;
}
//检查是否需要保证两次卡号一致
static int hf_double_check_exclude(const credential_t* cred){
	const uint8_t types[] = {
		HFTAG_CFG,
		HFTAG_WAVELYNX,
		HFTAG_HIDICLASS,
		HFTAG_SWIFTLANE,
		HFTAG_ACCESS_GRID,
	};
	
	for(int i = 0; i < sizeof(types); i++){
		if(cred->tag.type == types[i]){
			return 1;
		}
	}

	return 0;
}
static int rf_search_hf(uint32_t flags, uint32_t check, SimpleTag_T* tag){
	uint32_t status;
	credential_t cred;
	reader.bleFlags = 0;
	status = Reader_NFC_Discovery3(&cred, 0);
	if(status){
		//高频卡寻卡失败，寻蓝牙卡
		if((reader.attr & RD_ATTR_BT) && (flags & TAG_MASK_HIDICLASS)){
			return rf_search_ble(tag);
		}
		return status;
	}

	if(cred.clen != 0){
		tag->type = cred.tag.type;
		tag->ubit = cred.nbit;
		tag->ulen = cred.clen;
		if(cred.nbit != cred.clen * 8){
			uint64_t uid64 = 0;
			Mem_Reverse_Copy((uint8_t*)&uid64, cred.credential, cred.clen);
			uid64 <<= cred.clen * 8 - cred.nbit;		//左对齐
			Mem_Reverse_Copy(tag->uid, (uint8_t*)&uid64, cred.clen); 	//UID大端上传
		}
		else{
			memcpy(tag->uid, cred.credential, cred.clen);
		}
		
		return 0;
	}
	
	if(!check 
		|| hf_double_check_exclude(&cred)){
		*tag = cred.tag;
		if(tag->ubit == 0){
			tag->ubit = tag->ulen * 8;
		}
		return 0;
	}
	//
	uint16_t wPasPollConfig = hftype2mask(cred.tag.type);
	SimpleTag_T hf; 	//高频卡
	Reader_NFC_RfOff();
	phOsal_ThreadDelay(10);
	Reader_NFC_SetPollSeq(1);
	status = Reader_NFC_DiscoveryStd3(&hf, wPasPollConfig, 1);
	if(status){
		return -2;
	}
	
	//两次卡号相同，才返回OK。
	if(RfTag_Compare(&hf, &cred.tag)){
		return -3;
	}
	*tag = cred.tag;
	if(tag->ubit == 0){
		tag->ubit = tag->ulen * 8;
	}

	return 0;
}

static int rf_search_tag(buffer_t* command, buffer_t* response){
	SimpleTag_T tag;
	int ret = -1;
	uint8_t tech[2];
	uint32_t hfFirst = 1;
#if 1	
	if(reader.tag.type){
		//有卡
		if(reader.tag.type & TAG_TYPE_HF){
			//当前卡为高频卡
			//高频卡优先
			hfFirst = 1;
		}
		else{
			//当前卡为低频卡
			//低频卡优先
			hfFirst = 0;
		}
	}
	else{
		if(reader.config & RD_CFG_HFFirst){
			//高频卡优先
			hfFirst = 1;
		}
		else{
			//低频卡优先
			hfFirst = 0;
		}
	}
#endif	
	if(hfFirst){
		//高频卡优先
		tech[0] = 0x01;
		tech[1] = 0x00;
	}
	else{
		//低频卡优先
		tech[0] = 0x00;
		tech[1] = 0x01;
	}
	
	memset(&tag, 0, sizeof(tag));
	for(int i = 0; i < 2; i++){
		switch(tech[i]){
		case 0:{
			//低频卡
			if(reader.lfFlags){
				ret = rf_search_lf(reader.lfFlags, &tag);
			}
		}
		break;
		case 1:{
			//高频卡
			if(reader.hfFlags){
				Reader_LF_RfOff();
				ret = rf_search_hf(reader.hfFlags, 1, &tag);
				if(ret){
					Reader_NFC_RfOff();
				}
#if 0
				else{
					tag.ubit = tag.ulen * 8;
				}
#endif 
			}

		}
		break;
		}

		if(!ret && tag.ubit){
			break;
		}
	}	
	
	if(ret){
		rf_response_tag(response, NULL);
	}
	else{
		reader.tag = tag;
		rf_response_tag(response, &tag);
	}

	return ERR_NONE;
}


static int rf_set_rf_off(buffer_t* command, buffer_t* response){
	Reader_NFC_RfOff();
	Reader_LF_RfOff();
	return ERR_NONE;
}

static int rf_set_tag_types(buffer_t* command, buffer_t* response){
	reader.lfFlags = net_buf_simple_pull_le32(command);
	reader.hfFlags = net_buf_simple_pull_le32(command);

	if(!(reader.attr & RD_ATTR_HIDPROX)){
		//不支持HID Prox卡
		reader.lfFlags &= ~ TAG_MASK_HIDPROX;
	}
	
	//不支持HID iClass卡
	// reader.hfFlags &= ~ TAG_MASK_HIDICLASS;
	
	Reader_NFC_LoadProfile(reader.hfFlags, 0, 0, 0);
	return ERR_NONE;
}

static int rf_get_tag_types(buffer_t* command, buffer_t* response){
	uint32_t hf = reader.hfFlags;
	uint32_t lf = reader.lfFlags;
	hf &= ~(TAG_MASK_APPLEC);
	net_buf_simple_add_le32(response, lf);
	net_buf_simple_add_le32(response, hf);
	return ERR_NONE;
}

static int rf_get_support_tag_types(buffer_t* command, buffer_t* response){
	uint32_t hf = 0;
	uint32_t lf = 0;

	if(reader.attr & RD_ATTR_HF){
		hf = HFTAG_SUPPORT;
	}
	
#if 0
	if(reader.attr & RD_ATTR_BT){
		hf |= TAG_MASK_BLE;
	}
#endif 
	
	if(reader.attr & RD_ATTR_LF){
		lf = LFTAG_SUPPORT;
	}
	
	if(!(reader.attr & RD_ATTR_HIDPROX)){
		//不支持HID Prox卡
		lf &= ~ TAG_MASK_HIDPROX;
	}
	
	// hf &= ~ TAG_MASK_HIDICLASS;
	
	net_buf_simple_add_le32(response, lf);
	net_buf_simple_add_le32(response, hf);
	return ERR_NONE;
}

static const api_entry_t api_rf_list[5] = {
	[0] = rf_search_tag,
	[1] = rf_set_rf_off,
	[2] = rf_set_tag_types,
	[3] = rf_get_tag_types,
	[4] = rf_get_support_tag_types,
};
	
static int rf_api(buffer_t* command, buffer_t* response){
	const uint8_t num = sizeof(api_rf_list)/sizeof(api_rf_list[0]);
	return protocol_call_api(api_rf_list, num, command, response);
}

SIMPLE_API_DEFINE(API_CLASS_RF, rf_api);


